using System.Collections.Generic;
using AutoChess;
using ProtoBuf.Message;

namespace AutoChess
{
    class ACHero : GameActor
    {
        private AutoChessHeroInfoUI sceneUI;//场景UI
        
        private Table.DataModel.TableAutoChessHeroChess m_ChessHeroChessTable;
        private Table.DataModel.TableAutoChessHero m_ChessHeroTable;
        private Table.DataModel.TableHero m_HeroTable;

        private ActorAttrData m_attrData;

        private HeroData m_chessHeroData;

        public long OwnerPlayerUID
        {
            get { return m_chessHeroData.ownerPlayerId; }
        }

        public Table.DataModel.TableAutoChessHero ChessHeroTalbe
        {
            get { return m_ChessHeroTable; }
        }

        /// <summary>
        /// 专门封装一个ActorActionAttr 利于子类和组件的数据访问。 由于组件属于底层依赖于抽象，而组件子类需要访问
        /// 实体子类的数据的时候 如果不进行封装就会
        /// </summary>
        public ACGrid MapGrid 
        {
            get { return Attr.GetAtrribute<ACGrid>(ActorActionAttrDef.ACHero_GridData); }
            private set { Attr.SetAttribute(ActorActionAttrDef.ACHero_GridData,value); }
        }

        public int HeroID
        {
            get { return m_HeroTable.heroId; }
        }

        public int ChessID
        {
            get { return m_ChessHeroChessTable.chessId; }
        }

        public override ActorType GetActorType()
        {
            return ActorType.ChessHero;
        }
       
        public bool CreateACActor(HeroData heroData)
        {
            m_chessHeroData = heroData;
            m_ChessHeroChessTable = Table.Blo.AutoChessBlo.GetChessTable(heroData.chessId);
            m_HeroTable = Table.Blo.TableHeroBlo.GetTableHero(m_ChessHeroChessTable.heroId);

            //TODO 整合 ShaderSelectorCmpt
            if (Display.Create(HeroID,GetFathionId(),m_HeroTable.modelId))
            {
                BLogger.Error("Create ACHero failed,Display create error, ChessID:{0}, ModelId:{1},",heroData.chessId,m_HeroTable.heroId);
                return false;
            }
            
            m_attrData = new ActorAttrData();
            m_attrData.SetOwner(this);

            InitSkillConfig();
            InitBaseAttr();
            
            BUnityUtil.SetLayer(ActorGo,GameLayer.ActorLayer);
            return true;
        }

        public override void SetActorGoParent()
        {
            ActorTrans.transform.SetParent(AutoChessFieldViewCtr.Ins.HeroUnitRoot);
        }

        private int GetFathionId()
        {
            int fashionId = 0;
            if (OwnerPlayerUID != 0)
            {
                fashionId = AutoChessManager.Ins.cacheData.GetPlayerHeroFathionId(OwnerPlayerUID,HeroID);
            }
            return fashionId;
        }

        /// <summary>
        /// 初始化技能相关的配置
        /// </summary>
        private void InitSkillConfig()
        {
        }

        /// <summary>
        /// 初始化注册属性行为事件
        /// </summary>
        private void InitBaseAttr()
        {
           Event.AddEventListener<ACGrid>(ActorEventType.ACActorEnterGrid,OnActorEnterGrid,this);
           Event.AddEventListener(ActorEventType.ACActorLeaveGrid,OnActorLeaveGrid,this);
        }

        /// <summary>
        /// 创建完毕进入地图
        /// </summary>
        public override void OnEnterMap()
        {
            AddCmpt<ActorSM>();//添加基础状态组件
            AddCmpt<ACHeroBehaviorCmpt>();//添加行为表现的组件
            //进入格子
            var curGrid = AutoChessMapMgr.Ins.GetGridPos(m_chessHeroData.gridType, m_chessHeroData.gridIndex);
            OnActorEnterGrid(curGrid);
            if (curGrid.GridType != GridType.ShopGrid)
            {
                AutoChessHeroArgs args = new AutoChessHeroArgs() { logicObj = this };
                sceneUI = SceneUIManager.Instance.OpenUI(ActorGo.transform , true, "AutoChessHeroInfoUI", args) as AutoChessHeroInfoUI;
            }
        }

        public override void UpdateRunData(Dictionary<int, double> runAttrData)
        {
            ActorAttrData.UpdateActorData(m_attrData, runAttrData);
        }
        
        #region EventCall
        
        /// <summary>
        /// Actor进入一个格子
        /// </summary>
        private void OnActorEnterGrid(ACGrid acGrid)
        {
            var fromGrid = MapGrid;
            if (acGrid != null && acGrid.heroUnit == this)
            {
                OnActorLeaveGrid();
            }
            ActorEventHelper.SendOnActorEnterGrid(acGrid,this);
            MapGrid = acGrid;
            //一些行为逻辑放出去保持代码简洁
            ActorEventHelper.SendHeroEnterGridBehavior(this,fromGrid,acGrid,true);
        }

        private void OnActorLeaveGrid()
        {
            if (MapGrid != null)
            {
               ActorEventHelper.SendOnActorLeaveGrid(MapGrid);
            }
        }
        
        #endregion
        
    }
}